package tech.yunjing.train.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tech.yunjing.train.dao.AccountDao;
import tech.yunjing.train.dao.UserInfoDao;
import tech.yunjing.train.entity.Account;
import tech.yunjing.train.entity.UserInfo;
import tech.yunjing.train.service.AccountService;
import tech.yunjing.train.service.LoginService;
import tech.yunjing.train.service.exception.*;
import tech.yunjing.train.util.PasswordUtil;

import java.sql.Timestamp;
import java.util.*;

/**
 * 账户接口实现类，具体业务实现
 * Created by ZhangFan on 2017/6/8.
 */
@Service
public class AccountServiceImpl implements AccountService {
    @Autowired
    AccountDao accountDao;
    @Autowired
    private LoginService loginService;

    /**
     * 根据账户名获取账户信息
     *
     * @param accountName 账户名
     * @return Account对象
     */
    @Override
    public Account findByAccountName(String accountName) {
        //判断用户是否登录
        UserInfo userInfo = loginService.getUserAccount(accountName);
        if (userInfo == null) {
            throw new UserLoginException("请登录！");
        }
        return accountDao.findByAccountName(accountName);
    }

    /**
     * 根据账户Id获取账户信息
     *
     * @param accountId 账户id
     * @return 账户对象
     */
    @Override
    public Account findByAccountId(Integer accountId) {
        return accountDao.findByAccountId(accountId);
    }

    /**
     * 新增账户
     *
     * @param account 账户对象
     * @return 新增账户记录条数
     * @throws AccountNameException
     * @throws PaymentPasswordException
     * @throws AccountNotFoundException
     */
    @Override
    public int insertAccount(Account account) throws AccountNameException,
            PaymentPasswordException, AccountNotFoundException {
        //判断获取的用户账户名是否已存在（在调用findByAccountName（）方法时已确认登录）
        Account accountOne = accountDao.findByAccountName(account.getAccountName());
        if (accountOne != null) {
            throw new AccountNameException("用户已存在");
        }
        //校验传入的支付密码是否符合要求
        String reg = "(?!^\\\\d+$)(?!^[a-zA-Z]+$)(?!^[_#@]+$).{8,}";
        boolean password = account.getPaymentPassword().matches(reg);
        if (password) {
            //加密支付密码
            String paymentPassword = PasswordUtil.md5(account.getPaymentPassword());
            account.setPaymentPassword(paymentPassword);
            UserInfo userInfo = loginService.getUserAccount(account.getAccountName());
            account.setUserId(userInfo.getId());
            Date date = new Date();
            Timestamp createDate = new Timestamp(date.getTime());
            account.setCreateDate(createDate);
            return accountDao.insertAccount(account);
        } else {
            throw new PaymentPasswordException("密码格式不正确");
        }
    }

    /**
     * 根据账户名删除账户（逻辑删除）
     *
     * @param accountName 账户名
     * @return 删除记录条数
     */
    @Override
    public int deleteAccount(String accountName) throws AccountNotFoundException {
        //判断用户是否登录
        UserInfo userInfo = loginService.getUserAccount(accountName);
        if (userInfo == null) {
            throw new UserLoginException("请登录！");
        }
        //删除前需确认传入账户名是否已被删除（对应账户的状态是否改变）
        List<Account> accounts = accountDao.findNamesByAccountStatus();
        List<String> names = new ArrayList<>();
        for (int j = 0; j < accounts.size(); j++) {
            Account account = accounts.get(j);
            names.add(account.getAccountName());
        }
        if (names.contains(accountName)) {
            return accountDao.deleteAccount(accountName);
        } else {
            throw new AccountNotFoundException("用户不存在");
        }
    }

    /**
     * 根据账户名更改支付密码
     *
     * @param accountName        账户名
     * @param oldPaymentPassword 旧支付密码
     * @param newPaymentPassword 新支付密码
     * @return 更改记录条数
     * @throws AccountNameException
     * @throws PaymentPasswordException
     * @throws AccountNotFoundException
     */
    /**
     * 根据用户名更改支付密码
     *
     * @return int
     */
    @Override
    public int updatePaymentPasswordByAccountName(String accountName, String oldPaymentPassword, String newPaymentPassword)
            throws AccountNameException, PaymentPasswordException, AccountNotFoundException {
        //校验参数
        if (accountName == null || accountName.trim().isEmpty()) {
            throw new AccountNameException("请重新登录");
        }
        //校验传入的支付密码是否符合要求
        String reg = "(?!^\\\\d+$)(?!^[a-zA-Z]+$)(?!^[_#@]+$).{8,}";
        //判断新支付密码格式
        boolean newPassword = newPaymentPassword.matches(reg);
        //判断旧支付密码格式
        boolean oldPassword = oldPaymentPassword.matches(reg);
        //判断获取的用户账户名是否存在
        Account accountOne = accountDao.findByAccountName(accountName);
        if (accountOne == null) {
            throw new AccountNotFoundException("请重新登录");
        }
        //校验旧密码是否正确
        String paymentPassword = accountOne.getPaymentPassword();
        System.out.println(paymentPassword);
        //加密传入的旧支付密码
        String md5OldPassword = PasswordUtil.md5(oldPaymentPassword);
        System.out.println(md5OldPassword);
        //如果传入的旧密码和查询到的密码不一致抛出异常
        if (!(md5OldPassword.equals(paymentPassword))) {
            throw new PaymentPasswordException("旧密码输入错误");
        }
        //新支付密码是否符合格式要求，符合就修改
        if (newPassword && oldPassword) {
            //加密新支付密码
            paymentPassword = PasswordUtil.md5(newPaymentPassword);
            Map<String, Object> params = new HashMap();
            params.put("accountName", accountName);
            params.put("paymentPassword", paymentPassword);
            return accountDao.updatePaymentPasswordByAccountName(params);
        } else {
            throw new PaymentPasswordException("密码格式不正确");
        }
    }

    /**
     * 根据账户名更新余额
     *
     * @param accountName    账户名
     * @param accountBalance 账户余额
     * @return 更新记录条数
     */
    @Override
    public int updateBalanceByAccountName(Double accountBalance, String accountName)
            throws AccountNameException, AccountNotFoundException, AccountBalanceException {
        //判断用户是否登录
        UserInfo userInfo = loginService.getUserAccount(accountName);
        if (userInfo == null) {
            throw new UserLoginException("请登录！");
        }
        //校验参数
        if (accountName == null || accountName.trim().isEmpty()) {
            throw new AccountNameException("请重新登录");
        }
        if (accountBalance == null || accountBalance < 0) {
            throw new AccountBalanceException("账户余额异常，请稍后再试");
        }
        //判断获取的账户名是否存在
        Account accountOne = accountDao.findByAccountName(accountName);
        if (accountOne == null) {
            throw new AccountNotFoundException("请重新登录");
        }
        Map<String, Object> params = new HashMap();
        params.put("accountBalance", accountBalance);
        params.put("accountName", accountName);
        return accountDao.updateBalanceByAccountName(params);
    }
}
